package com.quiz.bis.util.text;

import com.quiz.bis.domain.model.ProcessedText;
import com.quiz.bis.service.impl.ImageHashService;
import com.quiz.file.domain.model.FileInfo;
import com.quiz.file.mapper.FileMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
@RequiredArgsConstructor
public class HybridSimilarityCalculator {
    private static final double TEXT_WEIGHT = 0.6;
    private static final double FORMULA_WEIGHT = 0.2;
    private static final double MEDIA_WEIGHT = 0.2;

    private final FileMapper fileMapper;
    private final ImageHashService imageHashService;
    private double calculateImageSimilarity(List<Long> imageIds1, List<Long> imageIds2) {
        if (imageIds1.isEmpty() && imageIds2.isEmpty()) {
            return 1.0;
        }
        if (imageIds1.isEmpty() || imageIds2.isEmpty()) {
            return 0.0;
        }

        // 获取所有图片的哈希值
        Map<Long, String> hashes1 = getImageHashes(imageIds1);
        Map<Long, String> hashes2 = getImageHashes(imageIds2);

        // 计算最佳匹配相似度
        double totalSimilarity = 0;
        int comparisons = 0;

        for (Map.Entry<Long, String> entry1 : hashes1.entrySet()) {
            for (Map.Entry<Long, String> entry2 : hashes2.entrySet()) {
                double similarity = imageHashService.compareHashes(entry1.getValue(), entry2.getValue());
                totalSimilarity += similarity;
                comparisons++;
            }
        }

        return comparisons > 0 ? totalSimilarity / comparisons : 0.0;
    }

    private Map<Long, String> getImageHashes(List<Long> imageIds) {
        Map<Long, String> hashes = new HashMap<>();
        for (Long imageId : imageIds) {
            FileInfo fileInfo = fileMapper.selectById(imageId);
            if (fileInfo != null && fileInfo.getMd5() != null) {
                hashes.put(imageId, fileInfo.getMd5());
            }
        }
        return hashes;
    }

    private static double calculateFormulaSimilarity(List<String> formulas1, List<String> formulas2) {
        if (formulas1.isEmpty() && formulas2.isEmpty()) {
            return 1.0;
        }
        if (formulas1.isEmpty() || formulas2.isEmpty()) {
            return 0.0;
        }

        // 使用Jaccard相似度计算公式相似度
        Set<String> set1 = new HashSet<>(formulas1);
        Set<String> set2 = new HashSet<>(formulas2);

        Set<String> intersection = new HashSet<>(set1);
        intersection.retainAll(set2);

        Set<String> union = new HashSet<>(set1);
        union.addAll(set2);

        return union.isEmpty() ? 0.0 : (double) intersection.size() / union.size();
    }

    private static double calculateMediaSimilarity(
            List<String> images1, List<String> images2,
            List<String> tables1, List<String> tables2
    ) {
        // 计算图片相似度
        double imageSimilarity = calculateJaccardSimilarity(images1, images2);

        // 计算表格相似度
        double tableSimilarity = calculateTableSimilarity(tables1, tables2);

        return (imageSimilarity + tableSimilarity) / 2;
    }

    private static double calculateJaccardSimilarity(List<String> list1, List<String> list2) {
        if (list1.isEmpty() && list2.isEmpty()) {
            return 1.0;
        }
        if (list1.isEmpty() || list2.isEmpty()) {
            return 0.0;
        }

        Set<String> set1 = new HashSet<>(list1);
        Set<String> set2 = new HashSet<>(list2);

        Set<String> intersection = new HashSet<>(set1);
        intersection.retainAll(set2);

        Set<String> union = new HashSet<>(set1);
        union.addAll(set2);

        return union.isEmpty() ? 0.0 : (double) intersection.size() / union.size();
    }

    private static double calculateTableSimilarity(List<String> tables1, List<String> tables2) {
        // 简化的表格相似度计算，实际中可以更复杂
        return calculateJaccardSimilarity(tables1, tables2);
    }
}
